#include <Svar/Svar.h>

using namespace sv;

Svar http=svar.import("svar_http");

std::string md5(std::string str){
    return SvarBuffer(str.data(),str.size()).md5();
}

int sum(int x,int y){
    return x+y;
}

Svar args(Svar req,Svar res) // this signature is reserved for common usage
{
    std::string method= req.call("method").as<std::string>();
    std::string path= req.call("path").as<std::string>();
    std::string type=req.call("get_header_value","Content-Type").as<std::string>();
    SvarBuffer  body=req.call("body").castAs<SvarBuffer>();
    Svar        parameters=req.call("parameters");

    if(parameters.isObject())
        return parameters;

    if(type=="application/json"){
        return Svar::parse_json(std::string(body.ptr(),body.size()));
    }

    return body.base64();
}

Svar detect(Svar task){
    Svar ret= {{"result","hello"}};
    return ret;
}

Svar get_service(){
    Svar service;
    service
            .def("md5",md5)
            .def("sum",sum,"x"_a,"y"_a)
            .def("args",args);

    service["detect"]=detect;
    service["name"]="sample";
    service["information"]["author"]="zhaoyong";

    return service;
}

void getpost(){
    // call function md5
    Svar response = http["get"]("http://localhost:1234/md5?args=a"); // use get to call
    std::cout<<response<<std::endl;
    response = http["post"]("http://localhost:1234/md5",Svar({{"args",{"a"}}}));// use post to call
    std::cout<<response<<std::endl;
    response = http["call"]("http://localhost:1234/md5","a"); // use call, must jsonable
    std::cout<<response<<std::endl;

    // call function sum
    response = http["get"]("http://localhost:1234/sum?args=1&args=2"); // use get to call
    std::cout<<response<<std::endl;
    response = http["get"]("http://localhost:1234/sum?x=1&y=2"); // use get with argument name
    std::cout<<response<<std::endl;
    response = http["post"]("http://localhost:1234/sum",Svar({{"args",{1,2}}}));// use post to call
    std::cout<<response<<std::endl;
    response = http["call"]("http://localhost:1234/sum",1,2); // use call, must jsonable
    std::cout<<response<<std::endl;

    // call function args
    response = http["get"]("http://localhost:1234/args?x=1&y=2"); // use get to call

    if (response.isUndefined()) // if failed, return Undefined
        return;
    else if(response.is("Response")) // for other response, a Response object will be returned
    {
       int         status=response.call("status").castAs<int>();
       std::string content_type=response.call("get_header_value","Content-Type").castAs<std::string>();
       SvarBuffer  body=response.call("body").castAs<SvarBuffer>();
    }
    else { // for json response, a json object will be returned
        std::cout<<response<<std::endl;
    }
}

int main(int argc,char** argv){
    svar.parseMain(argc,argv);

    int port=svar.arg("port",1234,"The service port");
    int alive=svar.arg("alive",true,"Keep alive or not");
    int client=svar.arg("client",false,"Client mode only");

    Svar Server;
    if(!client)
        Server=http["Server"]("localhost",1234,get_service());
    else
        getpost();

    while(alive)
        sleep(1);

    return 0;
}
